PROJECT(GCCCONFIG C)

INCLUDE(${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckVariableExists.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)

# Start with tests needed by PERFORM_C_TEST and PERFORM_C_TEST_RUN.
CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE)
CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H)
CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H)
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H)
CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
FOREACH(have
    HAVE_GETPAGESIZE
    HAVE_INTTYPES_H
    HAVE_MEMORY_H
    HAVE_STDINT_H
    HAVE_STDLIB_H
    HAVE_STRINGS_H
    HAVE_STRING_H
    HAVE_SYS_STAT_H
    HAVE_SYS_TYPES_H
    HAVE_SYS_PARAM_H
    HAVE_UNISTD_H
    )
  IF(NOT ${have})
    SET(${have} 0)
  ENDIF(NOT ${have})
ENDFOREACH(have)

MACRO(PERFORM_C_TEST var description invert)
  IF(${var}_COMPILED MATCHES "^${var}_COMPILED$")
    MESSAGE(STATUS "${description}")
    TRY_COMPILE(${var}_COMPILED
      ${GCCCONFIG_BINARY_DIR}
      ${GCCCONFIG_SOURCE_DIR}/gcc_c_tests.c
      OUTPUT_VARIABLE OUTPUT
      COMPILE_DEFINITIONS
      -DTEST_${var}
      -DHAVE_GETPAGESIZE=${HAVE_GETPAGESIZE}
      -DHAVE_INTTYPES_H=${HAVE_INTTYPES_H}
      -DHAVE_MEMORY_H=${HAVE_MEMORY_H}
      -DHAVE_STDINT_H=${HAVE_STDINT_H}
      -DHAVE_STDLIB_H=${HAVE_STDLIB_H}
      -DHAVE_STRINGS_H=${HAVE_STRINGS_H}
      -DHAVE_STRING_H=${HAVE_STRING_H}
      -DHAVE_SYS_STAT_H=${HAVE_SYS_STAT_H}
      -DHAVE_SYS_TYPES_H=${HAVE_SYS_TYPES_H}
      -DHAVE_SYS_PARAM_H=${HAVE_SYS_PARAM_H}
      -DHAVE_UNISTD_H=${HAVE_UNISTD_H}
      -DSTDC_HEADERS=${STDC_HEADERS}
      )
    IF(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
        "${description} compiled with the following output:\n${OUTPUT}\n\n")
    ELSE(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
        "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
    ENDIF(${var}_COMPILED)
    IF(${invert} MATCHES INVERT)
      IF(${var}_COMPILED)
        MESSAGE(STATUS "${description} - no")
      ELSE(${var}_COMPILED)
        MESSAGE(STATUS "${description} - yes")
      ENDIF(${var}_COMPILED)
    ELSE(${invert} MATCHES INVERT)
      IF(${var}_COMPILED)
        MESSAGE(STATUS "${description} - yes")
      ELSE(${var}_COMPILED)
        MESSAGE(STATUS "${description} - no")
      ENDIF(${var}_COMPILED)
    ENDIF(${invert} MATCHES INVERT)
  ENDIF(${var}_COMPILED MATCHES "^${var}_COMPILED$")
  IF(${invert} MATCHES INVERT)
    IF(${var}_COMPILED)
      SET(${var} 0)
    ELSE(${var}_COMPILED)
      SET(${var} 1)
    ENDIF(${var}_COMPILED)
  ELSE(${invert} MATCHES INVERT)
    IF(${var}_COMPILED)
      SET(${var} 1)
    ELSE(${var}_COMPILED)
      SET(${var} 0)
    ENDIF(${var}_COMPILED)
  ENDIF(${invert} MATCHES INVERT)
ENDMACRO(PERFORM_C_TEST)

MACRO(PERFORM_C_TEST_RUN var description zero nonzero invert)
  IF(${var}_RESULT MATCHES "^${var}_RESULT$")
    MESSAGE(STATUS "${description}")
    TRY_RUN(${var}_RESULT ${var}_COMPILED
      ${GCCCONFIG_BINARY_DIR}
      ${GCCCONFIG_SOURCE_DIR}/gcc_c_tests.c
      OUTPUT_VARIABLE OUTPUT
      COMPILE_DEFINITIONS
      -DTEST_${var}
      -DHAVE_GETPAGESIZE=${HAVE_GETPAGESIZE}
      -DHAVE_INTTYPES_H=${HAVE_INTTYPES_H}
      -DHAVE_MEMORY_H=${HAVE_MEMORY_H}
      -DHAVE_STDINT_H=${HAVE_STDINT_H}
      -DHAVE_STDLIB_H=${HAVE_STDLIB_H}
      -DHAVE_STRINGS_H=${HAVE_STRINGS_H}
      -DHAVE_STRING_H=${HAVE_STRING_H}
      -DHAVE_SYS_STAT_H=${HAVE_SYS_STAT_H}
      -DHAVE_SYS_TYPES_H=${HAVE_SYS_TYPES_H}
      -DHAVE_SYS_PARAM_H=${HAVE_SYS_PARAM_H}
      -DHAVE_UNISTD_H=${HAVE_UNISTD_H}
      -DSTDC_HEADERS=${STDC_HEADERS}
      )
    IF(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
        "${description} compiled with the following output:\n${OUTPUT}\n\n")
      IF(${invert} MATCHES INVERT)
        IF(${var}_RESULT)
          MESSAGE(STATUS "${description} - ${zero}")
        ELSE(${var}_RESULT)
          MESSAGE(STATUS "${description} - ${nonzero}")
        ENDIF(${var}_RESULT)
      ELSE(${invert} MATCHES INVERT)
        IF(${var}_RESULT)
          MESSAGE(STATUS "${description} - ${nonzero}")
        ELSE(${var}_RESULT)
          MESSAGE(STATUS "${description} - ${zero}")
        ENDIF(${var}_RESULT)
      ENDIF(${invert} MATCHES INVERT)
    ELSE(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
        "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
      MESSAGE(STATUS "${description} - test compilation failed")
    ENDIF(${var}_COMPILED)
  ENDIF(${var}_RESULT MATCHES "^${var}_RESULT$")
  IF(${var}_COMPILED)
    IF(${invert} MATCHES INVERT)
      IF(${var}_RESULT)
        SET(${var} 1)
      ELSE(${var}_RESULT)
        SET(${var} 0)
      ENDIF(${var}_RESULT)
    ELSE(${invert} MATCHES INVERT)
      IF(${var}_RESULT)
        SET(${var} 0)
      ELSE(${var}_RESULT)
        SET(${var} 1)
      ENDIF(${var}_RESULT)
    ENDIF(${invert} MATCHES INVERT)
  ENDIF(${var}_COMPILED)
ENDMACRO(PERFORM_C_TEST_RUN)

TEST_BIG_ENDIAN(HOST_WORDS_BIG_ENDIAN)
IF(HOST_WORDS_BIG_ENDIAN)
  SET(WORDS_BIGENDIAN 1)
ENDIF(HOST_WORDS_BIG_ENDIAN)
IF(NOT WORDS_BIGENDIAN)
  SET(HOST_WORDS_BIG_ENDIAN "")
ENDIF(NOT WORDS_BIGENDIAN)
PERFORM_C_TEST(gcc_ac_cv_c_const "checking for an ANSI C-conforming const" DIRECT)
PERFORM_C_TEST(HAVE_SYS_WAIT_H "checking for sys/wait.h that is POSIX.1 compatible" DIRECT)
PERFORM_C_TEST(TIME_WITH_SYS_TIME "checking whether time.h and sys/time.h may both be included" DIRECT)
PERFORM_C_TEST(TM_IN_TIME_H "checking whether struct tm is in time.h" DIRECT)
PERFORM_C_TEST(NEED_DECLARATION_ERRNO "checking whether errno must be declared" INVERT)
PERFORM_C_TEST(STDC_HEADERS "checking for ANSI C header files" DIRECT)
PERFORM_C_TEST(HAVE_SYS_RESOURCE_H_WITH_SYS_TIME_H
  "checking for sys/resource.h with sys/time.h" DIRECT)
PERFORM_C_TEST(HAVE_DIRENT_H
  "checking for dirent.h with sys/types.h" DIRECT)
PERFORM_C_TEST(HAVE_LANGINFO_CODESET
  "checking for nl_langinfo and CODESET" DIRECT)

CHECK_INCLUDE_FILE(alloca.h HAVE_ALLOCA_H)
CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H)
CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H)
CHECK_INCLUDE_FILE(machine/hal_sysinfo.h HAVE_MACHINE_HAL_SYSINFO_H)
CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H)
CHECK_INCLUDE_FILE(sys/file.h HAVE_SYS_FILE_H)
CHECK_INCLUDE_FILE(sys/mman.h HAVE_SYS_MMAN_H)
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILE(sys/pstat.h HAVE_SYS_PSTAT_H)
CHECK_INCLUDE_FILE(sys/resource.h HAVE_SYS_RESOURCE_H)
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILE(sys/sysctl.h HAVE_SYS_SYSCTL_H)
CHECK_INCLUDE_FILE(sys/sysinfo.h HAVE_SYS_SYSINFO_H)
CHECK_INCLUDE_FILE(sys/sysmp.h HAVE_SYS_SYSMP_H)
CHECK_INCLUDE_FILE(sys/systemcfg.h HAVE_SYS_SYSTEMCFG_H)
CHECK_INCLUDE_FILE(sys/table.h HAVE_SYS_TABLE_H)
CHECK_INCLUDE_FILE(sys/time.h HAVE_SYS_TIME_H)
CHECK_INCLUDE_FILE(stdio_ext.h HAVE_STDIO_EXT_H)
CHECK_INCLUDE_FILE(time.h HAVE_TIME_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(ctype.h HAVE_CTYPE_H)
CHECK_INCLUDE_FILE(stdio.h HAVE_STDIO_H)

CHECK_INCLUDE_FILE(vfork.h HAVE_VFORK_H)

CHECK_FUNCTION_EXISTS(_doprnt HAVE__DOPRNT)
CHECK_FUNCTION_EXISTS(__fsetlocking HAVE___FSETLOCKING)
CHECK_FUNCTION_EXISTS(asprintf HAVE_ASPRINTF)
CHECK_FUNCTION_EXISTS(atexit HAVE_ATEXIT)
CHECK_FUNCTION_EXISTS(basename HAVE_BASENAME)
CHECK_FUNCTION_EXISTS(bcmp HAVE_BCMP)
CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY)
CHECK_FUNCTION_EXISTS(bsearch HAVE_BSEARCH)
CHECK_FUNCTION_EXISTS(bzero HAVE_BZERO)
CHECK_FUNCTION_EXISTS(calloc HAVE_CALLOC)
CHECK_FUNCTION_EXISTS(clock HAVE_CLOCK)
CHECK_FUNCTION_EXISTS(ffs HAVE_FFS)
CHECK_FUNCTION_EXISTS(getcwd HAVE_GETCWD)
CHECK_FUNCTION_EXISTS(index HAVE_INDEX)
CHECK_FUNCTION_EXISTS(insque HAVE_INSQUE)
CHECK_FUNCTION_EXISTS(memchr HAVE_MEMCHR)
CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
CHECK_FUNCTION_EXISTS(mempcpy HAVE_MEMPCPY)
CHECK_FUNCTION_EXISTS(mkstemps HAVE_MKSTEMPS)
CHECK_FUNCTION_EXISTS(putenv HAVE_PUTENV)
CHECK_FUNCTION_EXISTS(random HAVE_RANDOM)
CHECK_FUNCTION_EXISTS(rename HAVE_RENAME)
CHECK_FUNCTION_EXISTS(rindex HAVE_RINDEX)
CHECK_FUNCTION_EXISTS(setenv HAVE_SETENV)
CHECK_FUNCTION_EXISTS(sigsetmask HAVE_SIGSETMASK)
CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF)
CHECK_FUNCTION_EXISTS(stpcpy HAVE_STPCPY)
CHECK_FUNCTION_EXISTS(stpncpy HAVE_STPNCPY)
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strchr HAVE_STRCHR)
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS(strncmp HAVE_STRNCMP)
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
CHECK_FUNCTION_EXISTS(strndup HAVE_STRNDUP)
CHECK_FUNCTION_EXISTS(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS(strstr HAVE_STRSTR)
CHECK_FUNCTION_EXISTS(strtod HAVE_STRTOD)
CHECK_FUNCTION_EXISTS(strtol HAVE_STRTOL)
CHECK_FUNCTION_EXISTS(strtoul HAVE_STRTOUL)
CHECK_FUNCTION_EXISTS(strverscmp HAVE_STRVERSCMP)
CHECK_FUNCTION_EXISTS(tmpnam HAVE_TMPNAM)
CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF)
CHECK_FUNCTION_EXISTS(vfprintf HAVE_VFPRINTF)
CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF)
CHECK_FUNCTION_EXISTS(vsprintf HAVE_VSPRINTF)
CHECK_FUNCTION_EXISTS(waitpid HAVE_WAITPID)
CHECK_FUNCTION_EXISTS(wait3 HAVE_WAIT3)
CHECK_FUNCTION_EXISTS(wait3 HAVE_WAIT4)
CHECK_FUNCTION_EXISTS(fork HAVE_FORK)
CHECK_FUNCTION_EXISTS(vfork HAVE_VFORK)

#-----------------------------------------------------------------------------
# Fake that these functions always exist until CMake bug #1775 is fixed.
#
# Workaround for CMake's existence testing problem with intrinsic functions
# on Windows with cl and /O2. If we don't do this, we get "intrinsic function,
# cannot be defined" errors when building optimized builds with cl on Windows.
# Change back to CHECK_FUNCTION_EXISTS calls when bug is fixed.
#
# CHECK_FUNCTION_EXISTS(memcmp HAVE_MEMCMP)
# CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
# CHECK_FUNCTION_EXISTS(memset HAVE_MEMSET)
SET(HAVE_MEMCMP 1 CACHE INTERNAL "Always have memcmp when building CableSwig...")
SET(HAVE_MEMCPY 1 CACHE INTERNAL "Always have memcpy when building CableSwig...")
SET(HAVE_MEMSET 1 CACHE INTERNAL "Always have memset when building CableSwig...")

CHECK_FUNCTION_EXISTS(canonicalize_file_name HAVE_CANONICALIZE_FILE_NAME)
CHECK_FUNCTION_EXISTS(getrusage HAVE_GETRUSAGE)
CHECK_FUNCTION_EXISTS(getsysinfo HAVE_GETSYSINFO)
CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
CHECK_FUNCTION_EXISTS(on_exit HAVE_ON_EXIT)
CHECK_FUNCTION_EXISTS(psignal HAVE_PSIGNAL)
CHECK_FUNCTION_EXISTS(pstat_getdynamic HAVE_PSTAT_GETDYNAMIC)
CHECK_FUNCTION_EXISTS(pstat_getstatic HAVE_PSTAT_GETSTATIC)
CHECK_FUNCTION_EXISTS(realpath HAVE_REALPATH)
CHECK_FUNCTION_EXISTS(sbrk HAVE_SBRK)
CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR)
CHECK_FUNCTION_EXISTS(strsignal HAVE_STRSIGNAL)
CHECK_FUNCTION_EXISTS(sysconf HAVE_SYSCONF)
CHECK_FUNCTION_EXISTS(sysctl HAVE_SYSCTL)
CHECK_FUNCTION_EXISTS(sysmp HAVE_SYSMP)
CHECK_FUNCTION_EXISTS(table HAVE_TABLE)
CHECK_FUNCTION_EXISTS(times HAVE_TIMES)

PERFORM_C_TEST(HAVE_SYS_ERRLIST "checking for variable sys_errlist" DIRECT)
PERFORM_C_TEST(HAVE_SYS_ERRLIST_IN_STDLIB_H
  "checking for sys_errlist in stdlib.h" DIRECT)
IF(NOT HAVE_SYS_ERRLIST)
  IF(HAVE_SYS_ERRLIST_IN_STDLIB_H)
    SET(HAVE_SYS_ERRLIST 1 CACHE INTERNAL "Have sys_errlist in stdlib.h.")
  ENDIF(HAVE_SYS_ERRLIST_IN_STDLIB_H)
ENDIF(NOT HAVE_SYS_ERRLIST)

PERFORM_C_TEST(HAVE_SYS_NERR "checking for variable sys_nerr" DIRECT)
PERFORM_C_TEST(HAVE_SYS_SIGLIST "checking for variable sys_siglist" DIRECT)
PERFORM_C_TEST(HAVE__DOPRNT "checking for variable _doprnt" DIRECT)
PERFORM_C_TEST(HAVE__SYSTEM_CONFIGURATION "checking for variable _system_configuration" DIRECT)

PERFORM_C_TEST(NEED_DECLARATION_CANONICALIZE_FILE_NAME
  "checking whether canonicalize_file_name must be declared" INVERT)

PERFORM_C_TEST(HAVE_UINTPTR_T "checking for uintptr_t" DIRECT)
PERFORM_C_TEST(HAVE_PID_T "checking for pid_t" DIRECT)

IF(NOT HAVE_PID_T)
  SET(pid_t int)
ENDIF(NOT HAVE_PID_T)

SET(GCC_UNIX_TESTS 1)
IF(WIN32)
  IF(NOT CYGWIN)
    SET(GCC_UNIX_TESTS 0)
  ENDIF(NOT CYGWIN)
ENDIF(WIN32)

IF(GCC_UNIX_TESTS)
  PERFORM_C_TEST_RUN(gcc_ac_cv_func_fork "checking for fork" yes no DIRECT)
  PERFORM_C_TEST_RUN(gcc_ac_cv_func_vfork "checking for vfork" yes no DIRECT)
  PERFORM_C_TEST_RUN(HAVE_MMAP "checking for working mmap" yes no DIRECT)
ELSE(GCC_UNIX_TESTS)
  SET(gcc_ac_cv_func_fork 0)
  SET(gcc_ac_cv_func_vfork 0)
  SET(HAVE_MMAP 0)
ENDIF(GCC_UNIX_TESTS)

PERFORM_C_TEST(CRAY_STACKSEG_END "checking whether alloca needs Cray hooks" DIRECT)
PERFORM_C_TEST_RUN(STACK_DIRECTION "checking stack direction for C alloca" -1 +1 DIRECT)
IF(STACK_DIRECTION_RESULT)
  SET(STACK_DIRECTION -1)
ELSE(STACK_DIRECTION_RESULT)
  SET(STACK_DIRECTION 1)
ENDIF(STACK_DIRECTION_RESULT)

# Some platforms (at least Mac) require sys/time.h to be included
# before sys/resource.h.  If including these together works, but
# sys/resource.h fails on its own, pretend we have it.
IF(NOT HAVE_SYS_RESOURCE_H)
  IF(HAVE_SYS_RESOURCE_H_WITH_SYS_TIME_H)
    SET(HAVE_SYS_RESOURCE_H 1)
  ENDIF(HAVE_SYS_RESOURCE_H_WITH_SYS_TIME_H)
ENDIF(NOT HAVE_SYS_RESOURCE_H)

IF(HAVE_GAS_WEAK MATCHES "^HAVE_GAS_WEAK$")
  MESSAGE(STATUS "checking assembler for .weak")
  TRY_COMPILE(HAVE_GAS_WEAK
    ${GCCCONFIG_BINARY_DIR}/gcc_asm_tests
    ${GCCCONFIG_SOURCE_DIR}/gcc_asm_tests
    GAT test_weak)
  IF(HAVE_GAS_WEAK)
    MESSAGE(STATUS "checking assembler for .weak - yes")
  ELSE(HAVE_GAS_WEAK)
    MESSAGE(STATUS "checking assembler for .weak - no")
  ENDIF(HAVE_GAS_WEAK)
ENDIF(HAVE_GAS_WEAK MATCHES "^HAVE_GAS_WEAK$")

IF(HAVE_GAS_WEAKREF MATCHES "^HAVE_GAS_WEAKREF$")
  MESSAGE(STATUS "checking assembler for .weakref")
  TRY_COMPILE(HAVE_GAS_WEAKREF
    ${GCCCONFIG_BINARY_DIR}/gcc_asm_tests
    ${GCCCONFIG_SOURCE_DIR}/gcc_asm_tests
    GAT test_weakref)
  IF(HAVE_GAS_WEAKREF)
    MESSAGE(STATUS "checking assembler for .weakref - yes")
  ELSE(HAVE_GAS_WEAKREF)
    MESSAGE(STATUS "checking assembler for .weakref - no")
  ENDIF(HAVE_GAS_WEAKREF)
ENDIF(HAVE_GAS_WEAKREF MATCHES "^HAVE_GAS_WEAKREF$")

IF(NOT gcc_ac_cv_func_vfork)
  SET(vfork fork)
ENDIF(NOT gcc_ac_cv_func_vfork)

SET(inline)
IF(gcc_ac_cv_c_const)
  SET(const)
ELSE(gcc_ac_cv_c_const)
  SET(const 1)
ENDIF(gcc_ac_cv_c_const)

IF(WORDS_BIGENDIAN)
  SET(BYTEORDER 4321)
ELSE(WORDS_BIGENDIAN)
  SET(BYTEORDER 1234)
ENDIF(WORDS_BIGENDIAN)

PERFORM_C_TEST(HAVE_UINT64_T "checking for type uint64_t" DIRECT)

# Look for a 64-bit integer type.
IF(HAVE_UINT64_T)
  SET(UNSIGNED_64BIT_TYPE "uint64_t")
ELSE(HAVE_UINT64_T)
  IF(SIZEOF_LONG MATCHES "^8$")
    SET(UNSIGNED_64BIT_TYPE "unsigned long")
  ELSE(SIZEOF_LONG MATCHES "^8$")
    IF(SIZEOF_LONG_LONG MATCHES "^8$")
      SET(UNSIGNED_64BIT_TYPE "unsigned long long")
    ENDIF(SIZEOF_LONG_LONG MATCHES "^8$")
  ENDIF(SIZEOF_LONG MATCHES "^8$")
ENDIF(HAVE_UINT64_T)

# Tests not done:
# checking for inline... (cached) inline
# checking for working fork... yes
# checking for working vfork... (cached) yes
# checking for working strncmp... yes
# checking for library containing strerror... none required
# checking for alloca

SET(HAVE_WORKING_FORK ${HAVE_FORK})
SET(HAVE_WORKING_VFORK ${HAVE_VFORK})
SET(HAVE_ALLOCA ${HAVE_ALLOCA_H})

IF(TM_IN_TIME_H)
  SET(TM_IN_SYS_TIME 0)
ELSE(TM_IN_TIME_H)
  SET(TM_IN_SYS_TIME ${HAVE_SYS_TIME_H})
ENDIF(TM_IN_TIME_H)

# gcc tests

IF(GCC_UNIX_TESTS)
  PERFORM_C_TEST_RUN(GETGROUPS_T "checking type of array argument to getgroups" "gid_t" "int" DIRECT)
ELSE(GCC_UNIX_TESTS)
  SET(GETGROUPS_T 0)
ENDIF(GCC_UNIX_TESTS)
PERFORM_C_TEST(STRING_WITH_STRINGS "checking whether string.h and strings.h may both be included" DIRECT)
PERFORM_C_TEST(_GNU_SOURCE "checking whether C library is GNU" DIRECT)
PERFORM_C_TEST(HAVE_LC_MESSAGES "checking for LC_MESSAGES" DIRECT)
PERFORM_C_TEST(HAVE_INITFINI_ARRAY "checking for .preinit_array/.init_array/.fini_array support" DIRECT)
PERFORM_C_TEST_RUN(HAVE_WORKING_MBSTOWCS "checking whether mbstowcs works" "yes" "no" DIRECT)
PERFORM_C_TEST_RUN(HAVE_PRINTF_PTR "checking whether the printf functions support %p" "yes" "no" DIRECT)
PERFORM_C_TEST(SYS_TYPES_HAS_OFF_T "checking whether sys/types.h has off_t" DIRECT)
PERFORM_C_TEST(SYS_TYPES_HAS_SSIZE_T "checking whether sys/types.h has ssize_t" DIRECT)
IF(GETGROUPS_T)
  SET(GETGROUPS_T gid_t)
ENDIF(GETGROUPS_T)
IF(NOT SYS_TYPES_HAS_OFF_T)
  SET(off_t long)
ENDIF(NOT SYS_TYPES_HAS_OFF_T)
IF(NOT SYS_TYPES_HAS_SSIZE_T)
  SET(ssize_t int)
ENDIF(NOT SYS_TYPES_HAS_SSIZE_T)

CHECK_INCLUDE_FILE(direct.h HAVE_DIRECT_H)
CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H)
CHECK_INCLUDE_FILE(langinfo.h HAVE_LANGINFO_H)
CHECK_INCLUDE_FILE(ldfcn.h HAVE_LDFCN_H)
CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H)
CHECK_INCLUDE_FILE(locale.h HAVE_LOCALE_H)
CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H)
CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
CHECK_INCLUDE_FILE(stddef.h HAVE_STDDEF_H)
CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H)
CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
CHECK_INCLUDE_FILE(sys/file.h HAVE_SYS_FILE_H)
CHECK_INCLUDE_FILE(sys/mman.h HAVE_SYS_MMAN_H)
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILE(sys/resource.h HAVE_SYS_RESOURCE_H)
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILE(sys/time.h HAVE_SYS_TIME_H)
CHECK_INCLUDE_FILE(sys/times.h HAVE_SYS_TIMES_H)
CHECK_INCLUDE_FILE(time.h HAVE_TIME_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(wchar.h HAVE_WCHAR_H)

CHECK_FUNCTION_EXISTS(alphasort HAVE_ALPHASORT)
CHECK_FUNCTION_EXISTS(atoll HAVE_ATOLL)
CHECK_FUNCTION_EXISTS(atoq HAVE_ATOQ)
CHECK_FUNCTION_EXISTS(clearerr_unlocked HAVE_CLEARERR_UNLOCKED)
CHECK_FUNCTION_EXISTS(clock HAVE_CLOCK)
CHECK_FUNCTION_EXISTS(dup2 HAVE_DUP2)
CHECK_FUNCTION_EXISTS(feof_unlocked HAVE_FEOF_UNLOCKED)
CHECK_FUNCTION_EXISTS(ferror_unlocked HAVE_FERROR_UNLOCKED)
CHECK_FUNCTION_EXISTS(fflush_unlocked HAVE_FFLUSH_UNLOCKED)
CHECK_FUNCTION_EXISTS(fgetc_unlocked HAVE_FGETC_UNLOCKED)
CHECK_FUNCTION_EXISTS(fgets_unlocked HAVE_FGETS_UNLOCKED)
CHECK_FUNCTION_EXISTS(fileno_unlocked HAVE_FILENO_UNLOCKED)
CHECK_FUNCTION_EXISTS(fprintf_unlocked HAVE_FPRINTF_UNLOCKED)
CHECK_FUNCTION_EXISTS(fputc_unlocked HAVE_FPUTC_UNLOCKED)
CHECK_FUNCTION_EXISTS(fputs_unlocked HAVE_FPUTS_UNLOCKED)
CHECK_FUNCTION_EXISTS(fread_unlocked HAVE_FREAD_UNLOCKED)
CHECK_FUNCTION_EXISTS(fwrite_unlocked HAVE_FWRITE_UNLOCKED)
CHECK_FUNCTION_EXISTS(getc_unlocked HAVE_GETC_UNLOCKED)
CHECK_FUNCTION_EXISTS(getchar_unlocked HAVE_GETCHAR_UNLOCKED)
CHECK_FUNCTION_EXISTS(getrlimit HAVE_GETRLIMIT)
CHECK_FUNCTION_EXISTS(getrusage HAVE_GETRUSAGE)
CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
CHECK_FUNCTION_EXISTS(kill HAVE_KILL)
CHECK_FUNCTION_EXISTS(mbstowcs HAVE_MBSTOWCS)
CHECK_FUNCTION_EXISTS(mincore HAVE_MINCORE)
CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
CHECK_FUNCTION_EXISTS(nl_langinfo HAVE_NL_LANGINFO)
CHECK_FUNCTION_EXISTS(putc_unlocked HAVE_PUTC_UNLOCKED)
CHECK_FUNCTION_EXISTS(putchar_unlocked HAVE_PUTCHAR_UNLOCKED)
CHECK_FUNCTION_EXISTS(scandir HAVE_SCANDIR)
CHECK_FUNCTION_EXISTS(setlocale HAVE_SETLOCALE)
CHECK_FUNCTION_EXISTS(setrlimit HAVE_SETRLIMIT)
CHECK_FUNCTION_EXISTS(strsignal HAVE_STRSIGNAL)
CHECK_FUNCTION_EXISTS(sysconf HAVE_SYSCONF)
CHECK_FUNCTION_EXISTS(times HAVE_TIMES)
CHECK_FUNCTION_EXISTS(wcswidth HAVE_WCSWIDTH)

CHECK_TYPE_SIZE("void*" SIZEOF_VOID_P)
CHECK_TYPE_SIZE("short" SIZEOF_SHORT)
CHECK_TYPE_SIZE("int" SIZEOF_INT)
CHECK_TYPE_SIZE("long" SIZEOF_LONG)
CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
IF(SIZEOF_LONG_LONG)
  SET(HAVE_LONG_LONG 1)
ENDIF(SIZEOF_LONG_LONG)
CHECK_TYPE_SIZE("_Bool" SIZEOF__BOOL)
IF(SIZEOF__BOOL)
  SET(HAVE__BOOL 1)
ENDIF(SIZEOF__BOOL)

# Skip this.
SET(NEED_64BIT_HOST_WIDE_INT 0)
IF(NEED_64BIT_HOST_WIDE_INT)
  IF(HAVE_LONG_LONG)
    SET(HOST_WIDE_INT "long long")
  ELSE(HAVE_LONG_LONG)
    SET(HOST_WIDE_INT "__int64")
  ENDIF(HAVE_LONG_LONG)
ELSE(NEED_64BIT_HOST_WIDE_INT)
  SET(HOST_WIDE_INT "long")
ENDIF(NEED_64BIT_HOST_WIDE_INT)

SET(ENABLE_ASSERT_CHECKING 1)
SET(ENABLE_CHECKING 1)
SET(ENABLE_RUNTIME_CHECKING 1)
SET(ENABLE_TREE_CHECKING 1)
SET(ENABLE_GC_CHECKING 1)
SET(ENABLE_RTL_FLAG_CHECKING 1)
SET(ENABLE_NLS 0)
SET(ENABLE_DECIMAL_FLOAT 0)

MACRO(CHECK_DECL_EXISTS symbol var)
  IF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
    MESSAGE(STATUS "Looking for declaration of ${symbol}")
    SET(CHECK_DECL_EXISTS_SYM ${symbol})
    SET(CHECK_DECL_EXISTS_VAR ${var})
    CONFIGURE_FILE(
      ${GCCCONFIG_SOURCE_DIR}/auto-host.h.in
      ${GCCCONFIG_BINARY_DIR}/gcc_check_decl.h @ONLY IMMEDIATE)
    CONFIGURE_FILE(
      ${GCCCONFIG_SOURCE_DIR}/gcc_check_decl.c.in
      ${GCCCONFIG_BINARY_DIR}/gcc_check_decl.c @ONLY IMMEDIATE)
    TRY_COMPILE(${var}_COMPILED
      ${GCCCONFIG_BINARY_DIR}
      ${GCCCONFIG_BINARY_DIR}/gcc_check_decl.c
      OUTPUT_VARIABLE OUTPUT
      COMPILE_DEFINITIONS -I\"${GCC_SOURCE_DIR}/gcc\" -I\"${GCC_SOURCE_DIR}/include\"
      )
    IF(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
        "Check for ${symbol} compiled with the following output:\n${OUTPUT}\n\n")
      MESSAGE(STATUS "Looking for declaration of ${symbol} - found")
    ELSE(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
        "Check for ${symbol} failed to compile with the following output:\n${OUTPUT}\n\n")
      MESSAGE(STATUS "Looking for declaration of ${symbol} - not found")
    ENDIF(${var}_COMPILED)
  ENDIF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
  IF(${var}_COMPILED)
    SET(${var} 1)
  ELSE(${var}_COMPILED)
    SET(${var} 0)
  ENDIF(${var}_COMPILED)
ENDMACRO(CHECK_DECL_EXISTS)

CHECK_DECL_EXISTS(ffs HAVE_DECL_FFS)
CHECK_DECL_EXISTS(snprintf HAVE_DECL_SNPRINTF)
CHECK_DECL_EXISTS(vsnprintf HAVE_DECL_VSNPRINTF)
CHECK_DECL_EXISTS(strverscmp HAVE_DECL_STRVERSCMP)

CHECK_DECL_EXISTS(getenv HAVE_DECL_GETENV)
CHECK_DECL_EXISTS(atol HAVE_DECL_ATOL)
CHECK_DECL_EXISTS(sbrk HAVE_DECL_SBRK)
CHECK_DECL_EXISTS(abort HAVE_DECL_ABORT)
CHECK_DECL_EXISTS(atof HAVE_DECL_ATOF)
CHECK_DECL_EXISTS(getcwd HAVE_DECL_GETCWD)
CHECK_DECL_EXISTS(getwd HAVE_DECL_GETWD)
CHECK_DECL_EXISTS(strsignal HAVE_DECL_STRSIGNAL)
CHECK_DECL_EXISTS(clearerr_unlocked HAVE_DECL_CLEARERR_UNLOCKED)
CHECK_DECL_EXISTS(feof_unlocked HAVE_DECL_FEOF_UNLOCKED)
CHECK_DECL_EXISTS(ferror_unlocked HAVE_DECL_FERROR_UNLOCKED)
CHECK_DECL_EXISTS(fflush_unlocked HAVE_DECL_FFLUSH_UNLOCKED)
CHECK_DECL_EXISTS(fgetc_unlocked HAVE_DECL_FGETC_UNLOCKED)
CHECK_DECL_EXISTS(fgets_unlocked HAVE_DECL_FGETS_UNLOCKED)
CHECK_DECL_EXISTS(fileno_unlocked HAVE_DECL_FILENO_UNLOCKED)
CHECK_DECL_EXISTS(fprintf_unlocked HAVE_DECL_FPRINTF_UNLOCKED)
CHECK_DECL_EXISTS(fputc_unlocked HAVE_DECL_FPUTC_UNLOCKED)
CHECK_DECL_EXISTS(fputs_unlocked HAVE_DECL_FPUTS_UNLOCKED)
CHECK_DECL_EXISTS(fread_unlocked HAVE_DECL_FREAD_UNLOCKED)
CHECK_DECL_EXISTS(fwrite_unlocked HAVE_DECL_FWRITE_UNLOCKED)
CHECK_DECL_EXISTS(getc_unlocked HAVE_DECL_GETC_UNLOCKED)
CHECK_DECL_EXISTS(getchar_unlocked HAVE_DECL_GETCHAR_UNLOCKED)
CHECK_DECL_EXISTS(putc_unlocked HAVE_DECL_PUTC_UNLOCKED)
CHECK_DECL_EXISTS(putchar_unlocked HAVE_DECL_PUTCHAR_UNLOCKED)
CHECK_DECL_EXISTS(strstr HAVE_DECL_STRSTR)
CHECK_DECL_EXISTS(errno HAVE_DECL_ERRNO)
CHECK_DECL_EXISTS(asprintf HAVE_DECL_ASPRINTF)
CHECK_DECL_EXISTS(vasprintf HAVE_DECL_VASPRINTF)
CHECK_DECL_EXISTS(malloc HAVE_DECL_MALLOC)
CHECK_DECL_EXISTS(realloc HAVE_DECL_REALLOC)
CHECK_DECL_EXISTS(calloc HAVE_DECL_CALLOC)
CHECK_DECL_EXISTS(free HAVE_DECL_FREE)
CHECK_DECL_EXISTS(basename HAVE_DECL_BASENAME)
CHECK_DECL_EXISTS(getopt HAVE_DECL_GETOPT)
CHECK_DECL_EXISTS(clock HAVE_DECL_CLOCK)

CHECK_DECL_EXISTS(getrlimit HAVE_DECL_GETRLIMIT)
CHECK_DECL_EXISTS(setrlimit HAVE_DECL_SETRLIMIT)
CHECK_DECL_EXISTS(getrusage HAVE_DECL_GETRUSAGE)
CHECK_DECL_EXISTS(ldgetname HAVE_DECL_LDGETNAME)
CHECK_DECL_EXISTS(sigaltstack HAVE_DECL_SIGALTSTACK)
CHECK_DECL_EXISTS(getpagesize HAVE_DECL_GETPAGESIZE)
CHECK_DECL_EXISTS(times HAVE_DECL_TIMES)

#-----------------------------------------------------------------------------
# We fake the following settings because we don't care about the backend.
SET(HAVE_MMAP_FILE 0)
SET(HAVE_MMAP_DEV_ZERO 0)
SET(HAVE_MMAP_ANON 0)
SET(HAVE_ICONV 0)
SET(HAVE_ICONV_H 0)
SET(ICONV_CONST 0)
SET(HAVE_OBSTACK 0)
SET(HAVE_GAS_BALIGN_AND_P2ALIGN 1)
SET(HAVE_GAS_MAX_SKIP_P2ALIGN 1)
SET(HAVE_GAS_SUBSECTION_ORDERING 1)
SET(HAVE_GAS_HIDDEN 1)
SET(HAVE_AS_LEB128 1)
SET(HAVE_GAS_SHF_MERGE 1)
SET(HAVE_AS_TLS 1)
SET(HAVE_GAS_FILDS_FISTS 1)
SET(HAVE_AS_GOTOFF_IN_DATA 1)
SET(HAVE_AS_GSTABS_DEBUG_FLAG 1)
SET(HAVE_AS_DWARF2_DEBUG_LINE 1)
SET(HAVE_AS_GDWARF2_DEBUG_FLAG 1)
SET(HAVE_LD_RO_RW_SECTION_MIXING 1)
SET(HAVE_LD_EH_FRAME_HDR 1)
SET(TARGET_LIBC_PROVIDES_SSP 0)
SET(HAVE_COMDAT_GROUP 0)
#-----------------------------------------------------------------------------

SET(PREFIX_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include")

MACRO(CHECK_TYPE_EXISTS symbol var)
  IF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
    MESSAGE(STATUS "Checking for ${symbol}")
    CONFIGURE_FILE(
      ${GCCCONFIG_SOURCE_DIR}/auto-host.h.in
      ${GCCCONFIG_BINARY_DIR}/gcc_test_auto_host.h @ONLY IMMEDIATE)
    SET(COMPILE_DEFINITIONS "-DTEST_${var} -DHELLO_WORLD")
    SET(INCLUDE_DIRECTORIES
      "${GCC_SOURCE_DIR}/gcc"
      "${GCC_SOURCE_DIR}/include"
      "${GCCCONFIG_BINARY_DIR}"
      )
    TRY_COMPILE(${var}_COMPILED
      ${GCCCONFIG_BINARY_DIR}
      ${GCCCONFIG_SOURCE_DIR}/gcc_c_tests.c
      OUTPUT_VARIABLE OUTPUT
      CMAKE_FLAGS
      "-DCOMPILE_DEFINITIONS:STRING=${COMPILE_DEFINITIONS}"
      "-DINCLUDE_DIRECTORIES:STRING=${INCLUDE_DIRECTORIES}"
      )
    IF(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
        "Check for ${symbol} compiled with the following output:\n${OUTPUT}\n\n")
      MESSAGE(STATUS "Checking for ${symbol} - found")
    ELSE(${var}_COMPILED)
      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
        "Check for ${symbol} failed to compile with the following output:\n${OUTPUT}\n\n")
      MESSAGE(STATUS "Checking for ${symbol} - not found")
    ENDIF(${var}_COMPILED)
  ENDIF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
  IF(${var}_COMPILED)
    SET(${var} 1)
  ELSE(${var}_COMPILED)
    SET(${var} 0)
  ENDIF(${var}_COMPILED)
ENDMACRO(CHECK_TYPE_EXISTS)

CHECK_TYPE_EXISTS("struct tms" HAVE_STRUCT_TMS)
CHECK_TYPE_EXISTS(clock_t HAVE_CLOCK_T)
#CHECK_TYPE_EXISTS(ino_t HAVE_INO_T)
#CHECK_TYPE_EXISTS(dev_t HAVE_DEV_T)

# Find the platform configuration.
IF(UNIX)
  SET(GCC_USE_PLATFORM_SCRIPT 1)
ENDIF(UNIX)
IF(MINGW)
  SET(GCC_USE_PLATFORM_SCRIPT 1)
ENDIF(MINGW)
SET(GCC_EXECUTED_PLATFORM_SCRIPT)
IF(GCC_USE_PLATFORM_SCRIPT)
  FIND_PROGRAM(GCC_SH NAMES sh PATHS /bin c:/msys/1.0/bin NO_CMAKE_FIND_ROOT_PATH )
  MARK_AS_ADVANCED(GCC_SH)
  IF(GCC_SH)
    EXEC_PROGRAM(${GCC_SH}
      ARGS
      "\"${GCCCONFIG_SOURCE_DIR}/gcc_platform.sh\""
      "\"${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake\""
      "\"${CMAKE_COMMAND}\"")
    SET(GCC_EXECUTED_PLATFORM_SCRIPT 1)
  ENDIF(GCC_SH)
ENDIF(GCC_USE_PLATFORM_SCRIPT)
IF(NOT GCC_EXECUTED_PLATFORM_SCRIPT)
  CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/gcc_platform_win32.cmake
                 ${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake @ONLY IMMEDIATE)
ENDIF(NOT GCC_EXECUTED_PLATFORM_SCRIPT)

# Load the platform configuration.
IF(EXISTS "${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake")
  INCLUDE("${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake")
ELSE(EXISTS "${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake")
  MESSAGE(FATAL_ERROR "Cannot find '${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake'")
ENDIF(EXISTS "${GCCCONFIG_BINARY_DIR}/gcc_platform.cmake")

IF(extra_modes)
  SET(EXTRA_MODES_FILE config/${extra_modes}) # ${GCC_SOURCE_DIR}/gcc/
  SET(EXTRA_CC_MODES 1)
ENDIF(extra_modes)

IF(NOT HAVE_DIRENT_H)
  CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/dirent.h
                 ${GCC_BINARY_DIR}/libcpp/dirent.h @ONLY IMMEDIATE)
ENDIF(NOT HAVE_DIRENT_H)

CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/libiberty_config.h.in
  ${GCC_BINARY_DIR}/libiberty/config.h @ONLY IMMEDIATE)
CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/libdecnumber_config.h.in
  ${GCC_BINARY_DIR}/libdecnumber/config.h @ONLY IMMEDIATE)
CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/libcpp_config.h.in
  ${GCC_BINARY_DIR}/libcpp/config.h @ONLY IMMEDIATE)
CONFIGURE_FILE(${GCCCONFIG_SOURCE_DIR}/auto-host.h.in
  ${GCC_BINARY_DIR}/gcc/auto-host.h @ONLY IMMEDIATE)
